home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
LIBRARY
/
CMPLTPAS
/
SEARCHER.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1988-07-25
|
9KB
|
224 lines
{--------------------------------------------------------------}
{ Searcher }
{ }
{ General-purpose file search unit }
{ }
{ by Jeff Duntemann }
{ Turbo Pascal V5.0 }
{ Last update 7/25/88 }
{ }
{ From: COMPLETE TURBO PASCAL 5.0 by Jeff Duntemann }
{ Scott, Foresman & Co., Inc. 1988 ISBN 0-673-38355-5 }
{--------------------------------------------------------------}
{$F+}
UNIT Searcher;
INTERFACE
USES DOS;
{ Note that this unit REQUIRES version 5.0 to compile! }
TYPE
HitProc = PROCEDURE(Foundit : SearchRec; InDirectory : String);
PROCEDURE SearchAll(Directory: String;
Spec : String;
Attribute : Byte;
DoIt : HitProc);
PROCEDURE SearchOne(Directory : String;
Spec : String;
Attribute : Byte;
Doit : Hitproc);
PROCEDURE SearchCurrent(Spec : String; Attribute : Byte; Doit : Hitproc);
IMPLEMENTATION
{->>>>SearchAll<<<<--------------------------------------------}
{ }
{ UNIT FILE: SEARCHER.PAS -- Last Modified 6/29/88 }
{ }
{ This is a search "engine" that traverses the entire DOS }
{ directory tree of the current disk volume, looking for files }
{ that match a filespec passed in Spec, and an attribute byte }
{ passed in Attribute. Whenever a matching file is found, the }
{ found file's DTA is passed to a procedural parameter, which }
{ then takes some action using the information in the DTA. }
{ }
{ The underlying logic of using FIND FIRST and FIND NEXT is }
{ almost identical to that of the LOCATE.PAS program, with the }
{ the difference that LOCATE.PAS only displays information on }
{ the found files. Passing different procedures in HitProc }
{ allows SearchAll to perform any action on a found file that }
{ you care to code up as a procedural parameter. }
{--------------------------------------------------------------}
PROCEDURE SearchAll(Directory: String;
Spec : String;
Attribute : Byte;
DoIt : HitProc);
VAR
CurrentDTA : SearchRec;
TempDirectory,NextDirectory : String;
BEGIN
{ First we look for any subdirectories. If any are found, }
{ we make a recursive call and search 'em too: }
{ Suppress unnecessary backslashes if we're searching the root: }
IF Directory = '\' THEN
TempDirectory := Directory + '*.*'
ELSE
TempDirectory := Directory + '\*.*';
{ Now make the FIND FIRST call for directories: }
FindFirst(TempDirectory,$10,CurrentDTA);
{ Here's the tricky stuff. If we get an indication that there is }
{ at least one more subdirectory within the current directory, }
{ (indicated by lack of error codes 2 or 18) we must search it }
{ by making a recursive call to SearchDirectory. We continue }
{ recursing and returning from the searched subdirectories until }
{ we get a code indicating none are left. }
WHILE (DOSError <> 2) AND (DOSError <> 18) DO
BEGIN
IF ((CurrentDTA.Attr AND $10) = $10) { If it's a directory }
AND (CurrentDTA.Name[1] <> '.') THEN { and not '.' or '..' }
BEGIN
{ Add a slash separating sections of the path if we're not }
{ currently searching the root: }
IF Directory <> '\' THEN NextDirectory := Directory + '\'
ELSE NextDirectory := Directory;
{ This begins with the current directory name, and copies }
{ the name of the found directory from the current DTA to }
{ the end of the current directory string. Then the new }
{ path is passed to the next recursive instantiation of }
{ SearchDirectory. }
NextDirectory := NextDirectory + CurrentDTA.Name;
{ Here's where we call "ourselves." }
SearchAll(NextDirectory,Spec,Attribute,DoIt);
END;
FindNext(CurrentDTA); { Now we look for more... }
END;
{ Now we can search for files, once we've run out of directories. }
{ This is conceptually simpler, as recursion is not involved. }
{ We combine the path and the file spec into one string, and make }
{ the FIND FIRST call: }
{ Suppress unnecessary slashes for root search: }
IF Directory <> '\' THEN
TempDirectory := Directory + '\' + Spec
ELSE TempDirectory := Directory + Spec;
{ Now, make the FIND FIRST call: }
FindFirst(TempDirectory,Attribute,CurrentDTA);
IF DOSError = 3 THEN { Bad path error }
Writeln('Path not found; check spelling.')
{ If we found something in the current directory matching the filespec, }
{ call the procedural parameter to take some action on the found DTA: }
ELSE IF (DOSError = 2) OR (DOSError = 18) THEN
{ Null; Directory is empty }
ELSE
BEGIN
DoIt(CurrentDTA,Directory); { Call the procedural parameter }
IF DOSError <> 18 THEN { More files are out there... }
REPEAT
FindNext(CurrentDTA); { Look for additional matches }
IF DOSError <> 18 THEN { More entries exist }
DoIt(CurrentDTA,Directory) { Call the procedural parameter }
UNTIL (DOSError = 18) OR (DOSError = 2) { Ain't no more! }
END
END;
{->>>>SearchOne<<<<--------------------------------------------}
{ }
{ UNIT FILE: SEARCHER.PAS -- Last Modified 5/28/88 }
{ }
{ This procedure is a subset of SearchAll, in that it only }
{ searches the directory specified in Directory, and not the }
{ entire directory tree of the current disk volume. In all }
{ other respects it operates the same way. }
{--------------------------------------------------------------}
PROCEDURE SearchOne(Directory : String;
Spec : String;
Attribute : Byte;
Doit : Hitproc);
VAR
TempDirectory : String;
CurrentDTA : SearchRec;
BEGIN
{ Suppress unnecessary slashes for root search: }
IF Directory <> '\' THEN
TempDirectory := Directory + '\' + Spec
ELSE TempDirectory := Directory + Spec;
{ Now, make the FIND FIRST call: }
FindFirst(TempDirectory,Attribute,CurrentDTA);
IF DOSError = 3 THEN { Bad path error }
Writeln('Path not found; check spelling.')
{ If we found something in the current directory matching the filespec, }
{ call the procedural parameter to take some action on the found DTA: }
ELSE IF (DOSError = 2) OR (DOSError = 18) THEN
{ Null; Directory is empty }
ELSE
IF DOSError <> 18 THEN { More files are out there... }
BEGIN
DoIt(CurrentDTA,Directory); { Call the procedural parameter }
REPEAT
FindNext(CurrentDTA); { Look for additional matches }
IF DOSError <> 18 THEN { More entries exist }
DoIt(CurrentDTA,Directory); { Call the procedural parameter }
UNTIL (DOSError = 18) OR (DOSError = 2) { Ain't no more! }
END
END;
{->>>>SearchCurrent<<<<----------------------------------------}
{ }
{ UNIT FILE: SEARCHER.PAS -- Last Modified 5/28/88 }
{ }
{ This procedure uses the same FIND FIRST/FIND NEXT logic of }
{ SearchAll and SearchOne, but only searches the current }
{ directory. It therefore does not need to be passed a }
{ parameter specifying the directory to be searched. }
{--------------------------------------------------------------}
PROCEDURE SearchCurrent(Spec : String; Attribute : Byte; Doit : Hitproc);
VAR
Directory : String;
BEGIN
GetDir(0,Directory); { Query DOS for the name of the current directory }
SearchOne(Directory,Spec,Attribute,DoIt);
END;
END.